package parspack;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;

public class Application implements IApplication {
	public static TypesCreator Types;
	public static List<Record> listRecords;
	public static ListTypes listTypes;
	public static byte[][] incidence;

	public Object start(IApplicationContext context) throws Exception {
		// create list of types from library
		System.out.println("Enter path to local repository:");
		Scanner in = new Scanner(System.in);
		String source = in.nextLine();

		listTypes = new ListTypes(new Path(source));
		Types = new TypesCreator(listTypes.compUnits);
		listRecords = new ArrayList<Record>();
		System.out.println("Enter word:");
		String input;
		Set<String> answer;
		Set<String> list;

		incidence = createFileOfincidences();
		System.out.println("Create clusters with mahout and enter path to file of clusers:");
		String pathToClust = in.nextLine();
		if (!pathToClust.equals("")) {
				createList(pathToClust);
		
			while (!(input = in.nextLine()).equals("-1")) {
				Query q = new Query();
				list = q.init(input);
				if (list != null) {
					answer = Answer.create(list);
					if (!answer.isEmpty())
						for (String x : answer) {
							System.out.println(x);
						}
					else {
						System.out.println("No matches.");
					}
				}
			}
		}

		return IApplication.EXIT_OK;
}
	
	
public void createList(String pathToClust) throws FileNotFoundException
	{
		byte[] localIncidence = new byte[listTypes.compUnits.size()];
		Scanner inputClusters = new Scanner(new File(pathToClust));
		Record currentRecord = new Record();

		// find new cluster-strings 
		while (inputClusters.hasNextLine()) {
			String stringCluster = inputClusters.nextLine();
			if (stringCluster.contains("-")) {
				inputClusters.nextLine();
				if (!currentRecord.listPostings.isEmpty())
					listRecords.add(currentRecord);

				currentRecord = new Record();
			} else {
	
				localIncidence = new byte[listTypes.compUnits.size()];
	    // init the incidence Vector for current term
				while (!stringCluster.equals("")) {

					String st = stringCluster.substring(0, stringCluster.indexOf(" "));
					stringCluster = stringCluster.substring(stringCluster.indexOf(" ") + 1);
					int k1 = Integer.parseInt(st);
					localIncidence[k1] = 1;
				}
				int index = 0;
		// find postings and create list for searching
				for (int i4 = 0; i4 < Types.listPostings.size(); i4++) {
					for (int i5 = 0; i5 < localIncidence.length; i5++) {
						if (incidence[i4][i5] != localIncidence[i5]) {
							break;
						} else {
							if (i5 == localIncidence.length - 1) {

								currentRecord.listPostings.add(Types.listPostings
										.get(i4));
								incidence[i4][0] = -1;
								index = 1;
							}
						}
					}
					if (index == 1) {
						break;
					}

				}
			}
		}
	}
	

public byte[][] createFileOfincidences() {

		byte[][] incidenceLocal = new byte[Types.listPostings.size()][listTypes.compUnits
				.size()];

		// sorting for easy-creating incidence matrix
		Collections.sort(listTypes.compUnits,
				new Comparator<MyCompilationUnit>() {
					public int compare(MyCompilationUnit first,
							MyCompilationUnit second) {
						return first.getElementName().compareToIgnoreCase(
								second.getElementName());
					}
				});
		Collections.sort(Types.listPostings, new Comparator<Posting>() {
			public int compare(Posting first, Posting second) {
				return first.name.compareToIgnoreCase(second.name);
			}
		});
		
		for (int i = 0; i < Types.listPostings.size(); i++) {
			Collections.sort(Types.listPostings.get(i).paths);
		}

		
		
		// create incidences vectors for clustering
		for (int i = 0; i < listTypes.compUnits.size(); i++)
			System.out.println(listTypes.compUnits.get(i).getElementName());
		try {
			FileWriter fstream = new FileWriter("/home/alexey/incidencesHuge.txt");
			BufferedWriter out = new BufferedWriter(fstream);

			for (int i = 0; i < Types.listPostings.size(); i++) {
				int indexInIncidenceVector = 0;
				for (int i1 = 0; i1 < listTypes.compUnits.size(); i1++) {
					if (listTypes.compUnits.get(i1).getElementName().compareTo(
							Types.listPostings.get(i).paths.get(indexInIncidenceVector)) == 0) {
						incidenceLocal[i][i1] = 1;
						indexInIncidenceVector++;
						if (indexInIncidenceVector == Types.listPostings.get(i).paths.size()) {
							for (int i3 = i1 + 1; i3 < incidenceLocal[0].length; i3++)
								incidenceLocal[i][i3] = 0;
							break;
						}
					} else
						incidenceLocal[i][i1] = 0;
				}

				for (int i2 = 0; i2 < listTypes.compUnits.size(); i2++) {
					out.write(String.valueOf(incidenceLocal[i][i2]));
					out.write(" ");
				}

				out.write("\r\n");
			}
			out.close();
		} catch (Exception e) {// Catch exception if any
			e.printStackTrace();
		}

		return incidenceLocal;

	}

	public void stop() {
	}
}

class Record {
	public List<Posting> listPostings;

	public Record() {
		this.listPostings = new ArrayList<Posting>();
	}
}